package com.es.disped.web.controller.index;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.es.disped.common.model.MsgModel;
import com.es.disped.core.annotation.LogInject;
import com.es.disped.core.controller.BaseController;
import com.es.disped.dao.model.LoginUser;
import com.es.disped.dao.model.MenuModel;
import com.es.disped.dao.model.UserType;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

@Api(value="首页")
@Controller
public class IndexController extends BaseController{
	
	private final String NAMESPACE="com.es.disped.dao.mapper.index.IndexCustomMapper";
    
	@LogInject
    private static Logger log;
	
    /**
     * 跳转到登录页<br>
     *
     * @return String 登录页路径
     */
    @RequestMapping("/sign")
    public String login()
    {
        if (this.isNull(this.getSessionUser())) 
        {
            return "login";
        } else 
        {
            return "redirect:/";
        }
    }
    
    /**
     * 跳转错误页（包含404、500等一系列错误页）<br>
     *
     * @return String 错误页路径
     */
    @RequestMapping("/{errorCode}/error")
    public @ResponseBody MsgModel error(@PathVariable String errorCode)
    {
        System.out.println(errorCode);
        return new MsgModel(Integer.valueOf(errorCode),"error");
    }
    
    /**
     * 获取系统菜单<br>
     *
     * @return List<MenuModel> 菜单列表集合
     */
    @ApiOperation(value="获取系统菜单",response=MsgModel.class,httpMethod="POST",notes="登录用户获取当前用户对应角色的系统菜单")
    @ApiImplicitParam(name="roleId",value="当前登录用户的角色ID",required=false,dataType="String")
    @RequestMapping(value="/init/menu",method=RequestMethod.POST)
    public @ResponseBody MsgModel menu(String roleId) {
        if (UserType.ADMIN.getValue().equals(this.getSessionUser().getUserType())) 
        {
            // 管理员菜单（在系统 xml 中配置）
            return getMenuForXml();
        } else 
        {
            // 一般用户菜单 general（根据角色获取对应菜单列表）
        	if(this.isNull(roleId))
        	{
        		Subject subject = SecurityUtils.getSubject();
       		 	LoginUser loginUser=(LoginUser) subject.getPrincipal();
        		if(!this.isNull(loginUser.getUserRoles()))
        		{
        			roleId=loginUser.getUserRoles().get(0).getRoleId();
        		}
        	}
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("menuId", "00000000000000000000000000000000");
            paramMap.put("roleId", roleId);
            paramMap.put("userId", this.getSessionUser().getUserId());

            List<MenuModel> list = new ArrayList<>();
            List<MenuModel> rootList = this.getService().selectList(NAMESPACE+".getMenu", paramMap);
            for (MenuModel menuModel : rootList) {
                menuModel.setChildren(getMenu(menuModel.getId(), roleId));
                list.add(menuModel);
            }
            return this.resultMsg(list.size()>0?HttpStatus.OK.value():HttpStatus.EXPECTATION_FAILED.value(),
            		list.size()>0?"":"系统菜单获取失败", list.size()>0?list:"");
        }
    }

    /**
     * 递归获取当前登录用户的所有菜单信息<br>
     *
     * @param pid 菜单父ID
     * @return List<MenuModel> 菜单列表集合
     */
	private List<MenuModel> getMenu(String pid, String roleId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("menuId", pid);
        paramMap.put("roleId", roleId);
        paramMap.put("userId", this.getSessionUser().getUserId());

        List<MenuModel> list = new ArrayList<>();
        List<MenuModel> menuList = this.getService().selectList(NAMESPACE+".getMenu", paramMap);
        for (MenuModel menuModel : menuList) {
            if (!this.isNull(menuModel.getId())) {
                menuModel.setChildren(getMenu(menuModel.getId(), roleId));
            }
            list.add(menuModel);
        }
        return list;
	}

	
    /**
     * 从 xml 中读取管理员菜单（adminMenu.xml）<br>
     *
     * @return List<MenuModel> 菜单列表集合
     */
	@SuppressWarnings("unchecked")
	private MsgModel getMenuForXml() {
		List<MenuModel> list = new ArrayList<>();
		 try {
			 InputStream inputStream = this.getClass().getResourceAsStream("/adminMenu.xml");
			 SAXReader reader = new SAXReader();
			 Document document = reader.read(inputStream);
			 Element element = document.getRootElement();
			 List<Element> menus = element.elements();
	            for(Element menu : menus) {
	            	MenuModel menuModelParent = new MenuModel();
	                List<MenuModel> childList = new ArrayList<>();
	                menuModelParent.setName(menu.attributeValue("name"));
	                menuModelParent.setIcon(this.isNull(menu.attributeValue("icon")) ? "zmdi zmdi-apps" : menu.attributeValue("icon"));
	                List<Element> menuItems = menu.elements();
	                for (Element menuItem : menuItems) {
	                	MenuModel menuModelChild = new MenuModel();
	                	 menuModelChild.setName(menuItem.elementText("name"));
	                     menuModelChild.setUrl(menuItem.elementText("url"));
	                     childList.add(menuModelChild);
	                }
	                menuModelParent.setChildren(childList);
	                list.add(menuModelParent);
	            }
		} catch (DocumentException e) {
			log.error("读取 xml 菜单信息失败");
		}
		return this.resultMsg(list.size()>0?HttpStatus.OK.value():HttpStatus.EXPECTATION_FAILED.value(),
				list.size()>0?"":"管理员菜单加载失败", list.size()>0?list:"");
	}
}
